﻿#include "maindrawscene.h"
#include "cmainframe.h"
#include "glext.h"
#include "nodemanager/wnodemanager.h"
#include "gui/guimanager.h"
#include "locomanager/locomanager.h"

#include <string>

initialiseSingleton(maindrawscene);

maindrawscene::maindrawscene(wxWindow* parent)
    : wxGLCanvas(parent, wxID_ANY, nullptr, wxDefaultPosition, wxDefaultSize),
      m_initialized(false),
      m_freetypeInitSuccessed(false)
{
    // 创建OpenGL上下文
    m_glContext = new MyGLContext(this);

    m_ContextMenu = new wxMenu();
    wxMenuItem* item = m_ContextMenu->Append(IDD_FILEMENU_SYSTEMINIT, wxT("系统初始.lua"), wxT("打开'系统初始.lua'"));
    item->SetBitmap(wxArtProvider::GetBitmap(wxART_GO_HOME, wxART_MENU));
    m_ContextMenuItemArts[item] = wxART_GO_HOME;
    item = m_ContextMenu->Append(IDD_FILEMENU_STATIONCONFIG, wxT("站场配置.lua"), wxT("打开'站场配置.lua'"));
    item->SetBitmap(wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_MENU));
    m_ContextMenuItemArts[item] = wxART_HELP_SIDE_PANEL;
    item = m_ContextMenu->Append(IDD_FILEMENU_SCENEDRAW, wxT("主场景绘制.lua"), wxT("打开'主场景绘制.lua'"));
    item->SetBitmap(wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_MENU));
    m_ContextMenuItemArts[item] = wxART_HELP_SETTINGS;
    item = m_ContextMenu->Append(IDD_FILEMENU_SCENEEVENT, wxT("主场景事件处理.lua"), wxT("打开'主场景事件处理.lua'"));
    item->SetBitmap(wxArtProvider::GetBitmap(wxART_HELP_BOOK, wxART_MENU));
    m_ContextMenuItemArts[item] = wxART_HELP_BOOK;
    item = m_ContextMenu->Append(IDD_FILEMENU_SCENEMESEVENT, wxT("主场景消息处理.lua"), wxT("打开'主场景消息处理.lua'"));
    item->SetBitmap(wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_MENU));
    m_ContextMenuItemArts[item] = wxART_ADD_BOOKMARK;

    m_NodeContextMenu = new wxMenu();
    m_Nodeitem = m_NodeContextMenu->Append(IDD_FIELMENU_NODEFILE, wxT("结点.lua"), wxT("打开'结点.lua'"));
    m_Nodeitem->SetBitmap(wxArtProvider::GetBitmap(wxART_HELP_PAGE, wxART_MENU));

    // 初始化freetype
    InitializeFreeType();

    m_updatetimer = new wxTimer(this, wxID_ANY);
    m_scriptTimer = new wxTimer(this, wxID_ANY+1);

    // 绑定菜单事件
    this->Bind(wxEVT_MENU, &maindrawscene::OnOpenFileMenu, this);

    // 绑定事件
    this->Bind(wxEVT_PAINT, &maindrawscene::OnPaint, this);
    this->Bind(wxEVT_SIZE, &maindrawscene::OnSize, this);
    this->Bind(wxEVT_TIMER, &maindrawscene::OnUpdateTimer, this);

    // 绑定所有鼠标事件到同一个处理函数
    this->Bind(wxEVT_LEFT_DOWN, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_LEFT_UP, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_MIDDLE_DOWN, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_MIDDLE_UP, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_RIGHT_DOWN, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_RIGHT_UP, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_MOTION, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_MOUSEWHEEL, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_ENTER_WINDOW, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_LEAVE_WINDOW, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_LEFT_DCLICK, &maindrawscene::OnMouseEvent, this);
    this->Bind(wxEVT_TIMER, &maindrawscene::OnSystemScriptTimer,
               this,m_scriptTimer->GetId());

    m_scriptTimer->Start(1000);
    m_updatetimer->Start(16); // 约60FPS
}

maindrawscene::~maindrawscene()
{
    // 卸载freetype
    shutdownFreeType();

    // 删除所有的纹理
    deleteAllTextures();

    delete m_ContextMenu;
    m_ContextMenu = NULL;
    delete m_NodeContextMenu;
    m_NodeContextMenu = NULL;
    delete m_glContext;
    m_glContext = NULL;
    delete m_updatetimer;
    m_updatetimer = NULL;
    delete m_scriptTimer;
    m_scriptTimer = NULL;
}

TextureInfo* maindrawscene::isExistTexture(unsigned int texid)
{
    std::unordered_map<wxString, TextureInfo>::iterator iter = m_textures.begin();
    for(;iter != m_textures.end();++iter)
    {
        if((*iter).second.id == texid)
            return &(*iter).second;
    }

    return NULL;
}

void maindrawscene::deleteAllTextures(void)
{
    std::unordered_map<wxString, TextureInfo>::iterator iter = m_textures.begin();
    for(;iter != m_textures.end();++iter)
    {
        glDeleteTextures(1, &((*iter).second.id));
    }

    m_textures.clear();
}

void maindrawscene::InitGL(void)
{
    m_glContext->SetCurrent();

    // 启用线段和多边形的抗锯齿
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //glEnable(GL_TEXTURE_2D);

    wxInitAllImageHandlers(); // 初始化所有图像处理器

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void maindrawscene::SetupTopLeftOrtho()
{
    wxSize size = GetClientSize();
    m_glContext->SetCurrent();

    glViewport(0, 0, size.x, size.y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // 关键设置：Y轴向下为正，原点在左上角
    glOrtho(0, size.x, size.y, 0, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

// 卸载freetype
void maindrawscene::shutdownFreeType()
{
    // 删除所有纹理
    for (auto& pair : m_characters) {
        glDeleteTextures(1, &pair.second.textureID);
    }

    // 释放 FreeType 资源
    if (m_face) FT_Done_Face(m_face);
    if (m_ft) FT_Done_FreeType(m_ft);
}

void maindrawscene::OnMouseEvent(wxMouseEvent& event)
{
    event.Skip();
    //std::lock_guard<std::mutex> lock(m_SceneMutex);

    if(event.ButtonDown(wxMOUSE_BTN_RIGHT))      // 右键菜单处理
    {
        if(CMainFrame::getSingleton().getWorkingMode() == WorkingMode::MODE_EIDTING)
        {
            WBaseNode *decNode = WNodeManager::getSingleton().getNodeByPoint(event.GetPosition());
            if(decNode != NULL &&
               (decNode->getNodeType() == NodeType::NODE_SWITCH ||
                decNode->getNodeType() == NodeType::NODE_SIGNAL))
            {
                m_Nodeitem->SetItemLabel(wxString::FromUTF8(decNode->getName())+wxT(".lua"));
                m_Nodeitem->SetHelp(wxString::Format(wxT("打开'%s.lua'"),decNode->getName()));
                PopupMenu(m_NodeContextMenu, event.GetPosition());
            }
            else if(decNode == NULL)
            {
                PopupMenu(m_ContextMenu, event.GetPosition());
            }
        }

        // 重置所有的控件状态
        GuiManager::getSingleton().resetAllNodes();
    }

    // 场景中所有结点处理鼠标事件
    WNodeManager::getSingleton().OnMMouseEvent(event);

    // 机车事件处理
    LocoManager::getSingleton().OnMMouseEvent(event);

    // GUI事件处理
    if(GuiManager::getSingleton().OnMMouseEvent(event) == NULL &&
       !WNodeManager::getSingleton().isLockedScreen())
    {
        // 主场景调用lua鼠标事件接口
        ScriptManager::getSingleton().callLuaFunctionWithSystemMouseEvent(
                                        GuiManager::getSingleton().getCurrentSelectedNode() == NULL ? -1 : GuiManager::getSingleton().getCurrentSelectedNode()->getID(),
                                        event);
    }
}

// 加载所有的字体
void maindrawscene::LoadAllCharacter(void)
{
    if(!m_freetypeInitSuccessed) return;

    glEnable(GL_TEXTURE_2D);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  // 禁用字节对齐限制

    // 加载常用汉字
    const wchar_t* commonChineseChars =
        L"的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严龙飞"
        L",.;:?!\"'()[]-~<>./\\|"
        L"1234567890"
        L"abcdefghijklmnopqrstuvwxyz"
        L"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    for (int i = 0; i < wcslen(commonChineseChars); i++) {
       if (!LoadCharacter(commonChineseChars[i])) {
           LOGE(wxString::Format("Failed to load character: %lc", commonChineseChars[i]).ToUTF8().data());
       }
    }

    // 预加载 ASCII 到 Unicode 基本汉字区 (0x4E00-0x9FFF)
    /*for (wchar_t c = 0; c < 128; ++c) {
        if (!LoadCharacter(c)) {
            LOGE(wxString::Format("Failed to load character1: %lc", c).ToStdString().c_str());
        }
    }

    // 加载常用汉字
    for (wchar_t c = 0x4E00; c <= 0x9FFF; ++c) {
        if (!LoadCharacter(c)) {
            LOGE(wxString::Format("Failed to load character2: %lc", c).ToStdString().c_str());
        }
    }*/

    glDisable(GL_TEXTURE_2D);
}

// 初始化 FreeType
bool maindrawscene::InitializeFreeType()
{
    if (FT_Init_FreeType(&m_ft)) {
        LOGE("Could not init FreeType Library");
        return false;
    }

    wxString pfontPath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+"/resources/fonts/SourceHanSansCN-Normal.otf";

    if (FT_New_Face(m_ft, pfontPath.ToStdString().c_str(), 0, &m_face)) {
        LOGE(wxString::Format("Failed to load font: %s", pfontPath).ToUTF8().data());
        return false;
    }

    // 设置默认字体大小
    FT_Set_Pixel_Sizes(m_face, 0, 14);

    m_freetypeInitSuccessed = true;

    return true;
}

bool maindrawscene::LoadCharacter(FT_ULong charcode)
{
    if (FT_Load_Char(m_face, charcode, FT_LOAD_RENDER)) {
        return false;
    }

    // 生成纹理
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    // 将单通道数据转换为RGBA
    int width = m_face->glyph->bitmap.width;
    int height = m_face->glyph->bitmap.rows;
    std::vector<unsigned char> rgbaData(width * height * 4);

    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
           int index = y * width + x;
           int rgbaIndex = index * 4;

           // 设置RGBA值
           rgbaData[rgbaIndex] = 255;     // R = 255 (白色)
           rgbaData[rgbaIndex + 1] = 255; // G = 255 (白色)
           rgbaData[rgbaIndex + 2] = 255; // B = 255 (白色)
           rgbaData[rgbaIndex + 3] = m_face->glyph->bitmap.buffer[index]; // A = 字形数据
        }
    }

    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_RGBA,
        width,
        height,
        0,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        rgbaData.data()
        );

    // 设置纹理选项
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // 存储字符
    Character character = {
        texture,
        glm::ivec2(m_face->glyph->bitmap.width, m_face->glyph->bitmap.rows),
        glm::ivec2(m_face->glyph->bitmap_left, m_face->glyph->bitmap_top),
        static_cast<GLuint>(m_face->glyph->advance.x)
    };

    m_characters[charcode] = character;
    return true;
}

/// 从文件中导入图片作为纹理
unsigned int maindrawscene::LoadTextureFromFile(const char* filePath, bool generateMipmaps)
{
    if(filePath == "") return 0;

    wxString decfilePath = wxString::FromUTF8(filePath);

    // 检查文件是否存在
    if (!wxFileExists(decfilePath)) {
        LOGE(wxString::Format(wxT("Failed to load texture: %s"), decfilePath).ToUTF8().data());
        return 0;
    }

    // 加载图片
    wxImage image;
    if (!image.LoadFile(decfilePath, wxBITMAP_TYPE_ANY)) {
        LOGE(wxString::Format(wxT("Failed to load texture: %s"), decfilePath).ToUTF8().data());
        return 0;
    }

    // 转换为RGBA格式（如果图片不是32位）
    if (!image.HasAlpha()) {
        image.InitAlpha();
    }

    // 确保图片数据是连续的
    if (!image.IsOk()) {
        LOGE(wxT("图片格式无效!"));
        return 0;
    }

    // 生成纹理ID
    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);

    // 设置纹理参数
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // 获取图片数据
    int width = image.GetWidth();
    int height = image.GetHeight();
    unsigned char* rgbData = image.GetData();
    unsigned char* alphaData = image.GetAlpha();

    // 将RGB+Alpha数据合并为RGBA
    std::vector<unsigned char> rgbaData(width * height * 4);
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            int index = (y * width + x);
            int rgbaIndex = index * 4;

            rgbaData[rgbaIndex] = rgbData[index * 3];      // R
            rgbaData[rgbaIndex + 1] = rgbData[index * 3 + 1]; // G
            rgbaData[rgbaIndex + 2] = rgbData[index * 3 + 2]; // B
            rgbaData[rgbaIndex + 3] = alphaData ? alphaData[index] : 255; // A
        }
    }

    // 上传纹理数据到GPU
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, rgbaData.data());

    // 生成mipmaps（如果需要）
    if (generateMipmaps) {
//        glGenerateMipmap(GL_TEXTURE_2D);
    }

    // 解绑纹理
    glBindTexture(GL_TEXTURE_2D, 0);

    m_textures[decfilePath] = TextureInfo(textureID, width, height);

    CMainFrame::getSingleton().printlog(LOG_LEVEL_INFO,wxString::Format(wxT("纹理:%s加载成功,ID:%ld!"),decfilePath,textureID).utf8_string());

    return textureID;
}

void maindrawscene::OnPaint(wxPaintEvent& event)
{    
    event.Skip();
    wxPaintDC dc(this);

    if (!m_initialized) {
        InitGL();
        LoadAllCharacter();
        m_initialized = true;

        // 调用lua初始函数
        ScriptManager::getSingleton().callLuaFunctionWithSystemInit();

        // 打开信号服务器
        CMainFrame::getSingleton().openSignalServer();
    }

    SetupTopLeftOrtho();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //std::lock_guard<std::mutex> lock(m_SceneMutex);

    // 结点绘制
    WNodeManager::getSingleton().draw(this);

    // 场景绘制脚本调用
    ScriptManager::getSingleton().callLuaFunctionWithMainDrawScene(this);

    // 机车绘制
    LocoManager::getSingleton().draw(this);

    // gui绘制
    GuiManager::getSingleton().draw(this);

    glFlush();

    // 交换缓冲区
    SwapBuffers();
}

void maindrawscene::OnOpenFileMenu(wxCommandEvent& event)
{
    if(event.GetId() == IDD_FIELMENU_NODEFILE)
    {
        CMainFrame::getSingleton().loadNodeScriptFile(m_Nodeitem->GetItemLabel());
        return;
    }

    std::map<wxMenuItem*,wxArtID>::iterator iter = m_ContextMenuItemArts.find(m_ContextMenu->FindItem(event.GetId()));
    if(iter != m_ContextMenuItemArts.end())
        CMainFrame::getSingleton().loadScriptFile((*iter).first->GetItemLabel(),
                                                  (*iter).second);

    event.Skip();
}

void maindrawscene::OnSize(wxSizeEvent& event)
{
    event.Skip();
    Refresh();

    // 结点工作区域改变
    WNodeManager::getSingleton().changeWorkingRect(this->GetClientSize());

    // 重新计算所有的股道
    LocoManager::getSingleton().changeWorkingRect();
}

void maindrawscene::OnUpdateTimer(wxTimerEvent& event)
{
    event.Skip();
    Refresh();

    // 调用lua更新函数
    ScriptManager::getSingleton().callLuaFuncitonWithSystemUpdate();

    // 结点更新
    WNodeManager::getSingleton().update();

    // 机车更新
    LocoManager::getSingleton().update();

    // 清除gc
    ScriptManager::getSingleton().lua_clear();
}

void maindrawscene::OnSystemScriptTimer(wxTimerEvent& event)
{
    WNodeManager::getSingleton().onProcessAllTimerEvent();
}

/// 画点
void maindrawscene::DrawPoint(wxRealPoint pos, wxColour color, float size)
{
    // 设置点大小
    glPointSize(size);

    // 设置颜色 (从wxColour转换为OpenGL格式)
    glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

    // 绘制点
    glBegin(GL_POINTS);
    glVertex2f(pos.x, pos.y);
    glEnd();
}

/// 画线
void maindrawscene::DrawLine(wxRealPoint startpos,wxRealPoint endpos,
              float borderWidth,
              wxColour color,
              float rotationDegrees)
{
    // 保存当前矩阵状态
    glPushMatrix();

    // 计算线条向量和长度
    wxRealPoint dir(endpos.x - startpos.x, endpos.y - startpos.y);
    float length = sqrt(dir.x * dir.x + dir.y * dir.y);

    // 只有长度大于0时才需要绘制
    if (length > 0.0001f) {
        // 计算中心点和单位方向向量
        wxPoint center((startpos.x + endpos.x) * 0.5f, (startpos.y + endpos.y) * 0.5f);
        wxRealPoint unitDir(dir.x / length, dir.y / length);

        // 平移到中心点
        glTranslatef(center.x, center.y, 0.0f);

        // 应用旋转
        glRotatef(rotationDegrees, 0.0f, 0.0f, 1.0f);

        // 平移回原点
        glTranslatef(-center.x, -center.y, 0.0f);

        // 启用线段抗锯齿
        //glEnable(GL_LINE_SMOOTH);
        //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
        //glEnable(GL_BLEND);
        //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        // 设置线条颜色
        glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

        // 设置线条宽度
        glLineWidth(borderWidth);

        // 计算扩展量（考虑线宽和抗锯齿）
        float extend = borderWidth * 0.10f;  // 经过优化的扩展系数

        // 绘制线条（向两端扩展）
        glBegin(GL_LINES);
        glVertex2f(startpos.x - unitDir.x * extend, startpos.y - unitDir.y * extend);
        glVertex2f(endpos.x + unitDir.x * extend, endpos.y + unitDir.y * extend);
        glEnd();

        // 禁用抗锯齿（如果需要保持其他绘制不变）
        //glDisable(GL_LINE_SMOOTH);
        //glDisable(GL_BLEND);
    }

    // 恢复矩阵状态
    glPopMatrix();

    // 重置线条宽度
    glLineWidth(1.0f);
}

wxString maindrawscene::GetDecodedText(const char* text)
{
    if (!text || !*text) return wxString(); // handle null/empty input

    // Thread-safe cache access
    //static std::mutex cacheMutex;
    //std::lock_guard<std::mutex> lock(cacheMutex);

    // Use string_view to avoid copy if possible (C++17)
    std::string key(text);

    auto it = m_textCache.find(key);
    if (it != m_textCache.end()) {
        return it->second;
    }

    // Try UTF-8 first, fallback to system encoding if fails
    wxString decStr = wxString::FromUTF8(text);

    // Store in cache (copy key if using string_view)
    m_textCache.emplace(std::string(key), decStr);

    return decStr;
}

void maindrawscene::DrawText1(const char* ttext,
                wxRealPoint pos,
                float scale,
                wxColour color,
                float rotationDegrees)
{
    if(ttext == "") return;

    glEnable(GL_TEXTURE_2D);
    glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

    std::wstring text = GetDecodedText(ttext).ToStdWstring();

    // 第一步：计算文本总宽度
    float totalWidth = 0.0f;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) {
                continue;
            }
        }
        Character ch = m_characters[c];
        totalWidth += (ch.advance >> 6) * scale;
    }

    pos.x -= totalWidth/2;

    // 保存当前模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    // 变换顺序：
    // 1. 移动到旋转中心点（pos + 总宽度/2）
    // 2. 应用旋转
    // 3. 移动到文本起始位置（-总宽度/2）
    glTranslatef(pos.x + totalWidth/2, pos.y, 0.0f);
    if (rotationDegrees != 0.0f) {
        glRotatef(rotationDegrees, 0.0f, 0.0f, 1.0f);
    }
    glTranslatef(-totalWidth/2, 0.0f, 0.0f);

    // 当前字符位置（相对于旋转后的坐标系）
    float currentX = 0.0f;

    // 遍历文本中所有字符
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) {
                continue;
            }
        }

        Character ch = m_characters[c];

        float xpos = currentX + ch.bearing.x * scale;
        float ypos = - (ch.size.y - ch.bearing.y) * scale;

        float w = ch.size.x * scale;
        float h = ch.size.y * scale;

        // 渲染字符纹理
        glBindTexture(GL_TEXTURE_2D, ch.textureID);
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(xpos, ypos);
            glTexCoord2f(1.0f, 0.0f); glVertex2f(xpos + w, ypos);
            glTexCoord2f(1.0f, 1.0f); glVertex2f(xpos + w, ypos + h);
            glTexCoord2f(0.0f, 1.0f); glVertex2f(xpos, ypos + h);
        glEnd();

        // 更新位置到下一个字形的原点
        currentX += (ch.advance >> 6) * scale;
    }

    // 恢复模型视图矩阵
    glPopMatrix();

    glDisable(GL_TEXTURE_2D);
}

/// 得到文本显示长度
wxRealPoint maindrawscene::getTextLength(wxString text,float scale)
{
    if(text == "") return wxRealPoint();

    double totalWidth = 0.0f;
    double maxHeight = 0.0f;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) {
                continue;
            }
        }
        Character ch = m_characters[c];
        totalWidth += (ch.advance >> 6) * scale;

        if (ch.size.y > maxHeight) {
            maxHeight = ch.size.y;
        }
    }

    return wxRealPoint(totalWidth,maxHeight);
}

void maindrawscene::DrawText4(
    const char* ttext,
    wxRealPoint pos,
    wxColour color,
    float rotationDegrees,
    int alignment,
    float scale)
{
    if(ttext == "") return;

    glEnable(GL_TEXTURE_2D);
    glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

    std::wstring text = GetDecodedText(ttext).ToStdWstring();

    // 第一步：计算文本总宽度
    float totalWidth = 0.0f;
    float maxHeight = 0.0f;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) {
                continue;
            }
        }
        Character ch = m_characters[c];
        totalWidth += (ch.advance >> 6) * scale;

        if (ch.size.y > maxHeight) {
            maxHeight = ch.size.y*scale;
        }
    }

    if ((TextAlignment)alignment == TextAlignment::RIGHT) {
        pos.x -= totalWidth;
    } else if ((TextAlignment)alignment == TextAlignment::LEFT){
        pos.y -= maxHeight;
    }else {
        pos.x -= totalWidth/2;
        pos.y -= maxHeight/2;
    }

    // 保存当前模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    // 变换顺序：
    // 1. 移动到旋转中心点（pos + 总宽度/2）
    // 2. 应用旋转
    // 3. 移动到文本起始位置（-总宽度/2）
    glTranslatef(pos.x + totalWidth/2, pos.y, 0.0f);
    if (rotationDegrees != 0.0f) {
        glRotatef(rotationDegrees, 0.0f, 0.0f, 1.0f);
    }
    glTranslatef(-totalWidth/2, 0.0f, 0.0f);

    // 当前字符位置（相对于旋转后的坐标系）
    float currentX = 0.0f;

    // 遍历文本中所有字符
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) {
                continue;
            }
        }

        Character ch = m_characters[c];

        float xpos = currentX + ch.bearing.x * scale;
        float ypos = - (ch.size.y - ch.bearing.y) * scale;

        float w = ch.size.x * scale;
        float h = ch.size.y * scale;

        // 渲染字符纹理
        glBindTexture(GL_TEXTURE_2D, ch.textureID);
        glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f); glVertex2f(xpos, ypos);
        glTexCoord2f(1.0f, 0.0f); glVertex2f(xpos + w, ypos);
        glTexCoord2f(1.0f, 1.0f); glVertex2f(xpos + w, ypos + h);
        glTexCoord2f(0.0f, 1.0f); glVertex2f(xpos, ypos + h);
        glEnd();

        // 更新位置到下一个字形的原点
        currentX += (ch.advance >> 6) * scale;
    }

    // 恢复模型视图矩阵
    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
}

void maindrawscene::DrawText3(
    const char* ttext,
    wxRealPoint pos,
    wxColour color,
    float rotationDegrees,
    int alignment,
    float offset)
{
    if (ttext == "") return;

    //wxString ddecStr(ttext, *m_utf8Conv);

    float scale = 1.0f;

    glEnable(GL_TEXTURE_2D);
    glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

    std::wstring text = GetDecodedText(ttext).ToStdWstring();

    // 计算文本总宽度和最大高度
    float totalWidth = 0.0f;
    float maxHeight = 0.0f;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) continue;
        }
        Character ch = m_characters[c];
        totalWidth += (ch.advance >> 6) * scale;
        if (ch.size.y > maxHeight) {
            maxHeight = ch.size.y;
        }
    }

    // 计算文本的起始位置（相对于 pos）
    float textStartX = 0.0f;
    if ((TextAlignment)alignment == TextAlignment::RIGHT) {
        textStartX = offset;  // 左对齐：pos 右侧 offset 像素处开始
    } else if ((TextAlignment)alignment == TextAlignment::LEFT){
        textStartX = -(totalWidth + offset);  // 右对齐：pos 左侧 offset 像素处结束
    }else {
        textStartX = -(totalWidth/2 + offset);
    }

    // 计算垂直偏移（使文本垂直居中）
    float textStartY = 0.0f;
    textStartY = -maxHeight * 0.5f * scale;  // 垂直居中调整

    // 保存当前矩阵
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    // 变换顺序：
    // 1. 移动到旋转中心点 (pos)
    // 2. 应用旋转
    // 3. 移动到文本起始位置 (textStartX, textStartY)
    glTranslatef(pos.x, pos.y, 0.0f);
    if (rotationDegrees != 0.0f) {
        glRotatef(rotationDegrees, 0.0f, 0.0f, 1.0f);
    }
    glTranslatef(textStartX, textStartY, 0.0f);

    // 渲染每个字符
    float currentX = 0.0f;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) continue;
        }

        Character ch = m_characters[c];
        float xpos = currentX + ch.bearing.x * scale;
        float ypos = -(ch.size.y - ch.bearing.y) * scale;
        float w = ch.size.x * scale;
        float h = ch.size.y * scale;

        glBindTexture(GL_TEXTURE_2D, ch.textureID);
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(xpos, ypos);
            glTexCoord2f(1.0f, 0.0f); glVertex2f(xpos + w, ypos);
            glTexCoord2f(1.0f, 1.0f); glVertex2f(xpos + w, ypos + h);
            glTexCoord2f(0.0f, 1.0f); glVertex2f(xpos, ypos + h);
        glEnd();

        currentX += (ch.advance >> 6) * scale;
    }

    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
}

void maindrawscene::DrawText2(const char* ttext,
                wxRect displayRect,    // 文本显示区域（包含位置和大小）
                float scale,
                wxColour color,
                float rotationDegrees,
                bool enableClipping,
                bool centerHorizontally,  // 水平居中
                bool centerVertically)     // 垂直居中
{
    if(ttext == "" || displayRect.width <= 0 || displayRect.height <= 0) return;

    // 启用裁剪测试
    if(enableClipping) {
        glEnable(GL_SCISSOR_TEST);
        glScissor(displayRect.x,
                 this->GetClientSize().GetHeight() - displayRect.y - displayRect.height,
                 displayRect.width,
                 displayRect.height);
    }

    glEnable(GL_TEXTURE_2D);
    glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

    std::wstring text = GetDecodedText(ttext).ToStdWstring();

    // 1. 计算文本总尺寸
    float totalWidth = 0.0f;
    float maxHeight = 0.0f;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) {
            if (!LoadCharacter(c)) continue;
        }
        Character ch = m_characters[c];
        totalWidth += (ch.advance >> 6) * scale;
        maxHeight = std::max(maxHeight, ch.size.y * scale);
    }

    // 2. 计算起始位置（考虑居中选项）
    float startX = displayRect.x;
    float startY = displayRect.y;

    if (centerHorizontally) {
        startX += (displayRect.width - totalWidth) / 2.0f;
    }
    if (centerVertically) {
        startY += (displayRect.height - maxHeight) / 2.0f;
    }

    // 3. 保存当前矩阵状态
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    // 4. 应用变换：移动到中心点 -> 旋转 -> 移动到起始位置
    if (rotationDegrees != 0.0f) {
        float centerX = displayRect.x + displayRect.width / 2.0f;
        float centerY = displayRect.y + displayRect.height / 2.0f;

        glTranslatef(centerX, centerY, 0.0f);
        glRotatef(rotationDegrees, 0.0f, 0.0f, 1.0f);
        glTranslatef(-centerX, -centerY, 0.0f);
    }

    // 5. 渲染字符
    float currentX = startX;
    for (wchar_t c : text) {
        if (m_characters.find(c) == m_characters.end()) continue;

        Character ch = m_characters[c];
        float xpos = currentX + ch.bearing.x * scale;
        float ypos = startY - (ch.size.y - ch.bearing.y) * scale;
        float w = ch.size.x * scale;
        float h = ch.size.y * scale;

        glBindTexture(GL_TEXTURE_2D, ch.textureID);
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(xpos, ypos);
            glTexCoord2f(1.0f, 0.0f); glVertex2f(xpos + w, ypos);
            glTexCoord2f(1.0f, 1.0f); glVertex2f(xpos + w, ypos + h);
            glTexCoord2f(0.0f, 1.0f); glVertex2f(xpos, ypos + h);
        glEnd();

        currentX += (ch.advance >> 6) * scale;
    }

    // 6. 恢复状态
    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
    if(enableClipping) {
        glDisable(GL_SCISSOR_TEST);
    }
}

/// 画圆
void maindrawscene::DrawCircle(wxRealPoint pos, float radius, int segments,
                               wxColour fillColor,
                               wxColour borderColor,float borderWidth,
                               float scale)
{
    // 仅缩放半径，不缩放圆心位置
    float scaledRadius = radius * scale;

    // 1. 绘制填充的圆
    if (fillColor.Alpha() > 0) {
        glColor4ub(fillColor.Red(), fillColor.Green(), fillColor.Blue(), fillColor.Alpha());
        glBegin(GL_TRIANGLE_FAN);
        glVertex2f(pos.x, pos.y); // 圆心位置不变
        for (int i = 0; i <= segments; ++i) {
            float angle = 2.0f * M_PI * float(i) / float(segments);
            float x = scaledRadius * cosf(angle);
            float y = scaledRadius * sinf(angle);
            glVertex2f(pos.x + x, pos.y + y);
        }
        glEnd();
    }

    // 2. 绘制边框
    if (borderColor.Alpha() > 0 && borderWidth > 0.0f) {
        glLineWidth(borderWidth); // 可选：是否让边框宽度也缩放？
        glColor4ub(borderColor.Red(), borderColor.Green(), borderColor.Blue(), borderColor.Alpha());
        glBegin(GL_LINE_LOOP);
        for (int i = 0; i < segments; ++i) {
            float angle = 2.0f * M_PI * float(i) / float(segments);
            float x = scaledRadius * cosf(angle);
            float y = scaledRadius * sinf(angle);
            glVertex2f(pos.x + x, pos.y + y);
        }
        glEnd();
        glLineWidth(1.0f); // 恢复默认线宽
    }
}

/**
 * 画矩形
 *
 * @param rect 要画的矩形框
 * @param color 矩形框的颜色
 * @param angle 矩形框的显示角度
 * @param rotationAnchor 矩形框旋转的锚点
 * @param scaleX,scaleY 缩放
 * @param filled 是否填充矩形
 * @param borderColor 边框颜色
 * @param borderWidth 边框宽度
 */
void maindrawscene::DrawRectangle(wxRect rect,wxColour color,
                                  float angle,wxRealPoint rotationAnchor,
                                  float scaleX, float scaleY,
                                  bool filled, wxColour borderColor,float borderWidth)
{
    // 保存当前矩阵状态
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushMatrix();

    // 应用变换：平移→旋转→缩放→平移
    glTranslatef(rotationAnchor.x, rotationAnchor.y, 0.0f);
    glRotatef(angle, 0.0f, 0.0f, 1.0f);
    glScalef(scaleX, scaleY, 1.0f);
    glTranslatef(rect.GetX() - rotationAnchor.x, rect.GetY() - rotationAnchor.y, 0.0f);

    // 绘制实心矩形（如果有填充）
    if(filled)
    {
        glColor4f(color.Red()/255.0f, color.Green()/255.0f, color.Blue()/255.0f,
                  color.Alpha()/255.0f);
        glBegin(GL_QUADS);
            glVertex2f(0, 0);
            glVertex2f(rect.GetWidth(), 0);
            glVertex2f(rect.GetWidth(), rect.GetHeight());
            glVertex2f(0, rect.GetHeight());
        glEnd();
    }

    // 绘制边框（如果有边框宽度）
    if(borderWidth > 0)
    {
        glDisable(GL_LINE_SMOOTH);
        glDisable(GL_BLEND);

        // 设置线宽和颜色
        glLineWidth(borderWidth);
        glColor4f(borderColor.Red()/255.0f, borderColor.Green()/255.0f,
                 borderColor.Blue()/255.0f,
                 borderColor.Alpha()/255.0f);

        // 这里不再减去borderWidth，直接使用矩形完整尺寸
        const float overlap = 0.65f; // 轻微重叠，抵消浮点误差
        glBegin(GL_LINE_LOOP);
        glVertex2f(-overlap, -overlap);
        glVertex2f(rect.GetWidth() + overlap, -overlap);
        glVertex2f(rect.GetWidth() + overlap, rect.GetHeight() + overlap);
        glVertex2f(-overlap, rect.GetHeight() + overlap);
        glEnd();

        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
    }

    // 恢复矩阵状态
    glPopMatrix();
    glPopAttrib();
}

/// 画纹理
void maindrawscene::DrawTexture(unsigned int textureid,
                 wxRealPoint position,
                 wxSize size,
                 float rotation,
                 wxColour color,
                 wxRect uvRect)
{
    if (textureid <= 0) return;

    TextureInfo* decTextureInfo = isExistTexture(textureid);
    if(decTextureInfo == NULL)
        return;

    // 计算实际绘制尺寸
    wxSize actualSize = size;
    if (actualSize == wxDefaultSize) {
        actualSize = wxSize(decTextureInfo->width, decTextureInfo->height);
    }

    // 计算UV矩形（如果使用默认值(0,0,0,0)，则使用整个纹理）
    wxRect actualUvRect = uvRect;
    if (uvRect.width == 0 && uvRect.height == 0) {
        actualUvRect = wxRect(0, 0, decTextureInfo->width, decTextureInfo->height);
    }

    // 启用纹理和混合
    glEnable(GL_TEXTURE_2D);
    //glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // 设置颜色
    glColor4ub(color.Red(), color.Green(), color.Blue(), color.Alpha());

    // 绑定纹理
    glBindTexture(GL_TEXTURE_2D, textureid);

    // 保存当前矩阵状态
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    // 移动到绘制位置中心
    glTranslatef(position.x + actualSize.x / 2.0f,
                 position.y + actualSize.y / 2.0f, 0.0f);

    // 应用旋转
    if (rotation != 0.0f) {
        glRotatef(rotation, 0.0f, 0.0f, 1.0f);
    }

    // 移动到相对原点
    glTranslatef(-actualSize.x / 2.0f, -actualSize.y / 2.0f, 0.0f);

    // 计算正确的纹理坐标（归一化到0-1范围）
    float texLeft = static_cast<float>(actualUvRect.x) / decTextureInfo->width;
    float texRight = static_cast<float>(actualUvRect.x + actualUvRect.width) / decTextureInfo->width;
    float texBottom = static_cast<float>(actualUvRect.y) / decTextureInfo->height;
    float texTop = static_cast<float>(actualUvRect.y + actualUvRect.height) / decTextureInfo->height;

    // OpenGL纹理坐标原点在左下角，所以需要翻转Y坐标
    texBottom = 1.0f - texBottom;
    texTop = 1.0f - texTop;

    // 绘制纹理四边形
    glBegin(GL_QUADS);
    glTexCoord2f(texLeft, texTop);     glVertex2f(0.0f, 0.0f);
    glTexCoord2f(texRight, texTop);    glVertex2f(actualSize.x, 0.0f);
    glTexCoord2f(texRight, texBottom); glVertex2f(actualSize.x, actualSize.y);
    glTexCoord2f(texLeft, texBottom);  glVertex2f(0.0f, actualSize.y);
    glEnd();

    // 恢复矩阵状态
    glPopMatrix();

    // 重置颜色
    //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

    // 解绑纹理并禁用状态
    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
    //glDisable(GL_BLEND);
}
